package com.buddy.summary.code.thread;

import org.junit.Test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

public class ThreadDemo {
    private static BlockingQueue<String> queue = new LinkedBlockingDeque<>(10);
    private static ExecutorService pool = Executors.newFixedThreadPool(2);
    class Factory {

        synchronized void produce(String ele) {
            boolean flag = false;
            try {
                if (queue.size() >= 10) {
                    System.out.println(Thread.currentThread().getName() + "【"+queue.size()+"】Producer wait!!!");
                    wait();
                    flag = true;
                }
                if (flag) {
                    System.out.println(Thread.currentThread().getName() + "（Producer被notify了）...");
                }
                queue.put(ele);
                notify();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        synchronized void consume() {
            boolean flag = false;
            try {
                if (queue.isEmpty()) {
                    System.out.println(Thread.currentThread().getName() + "【"+queue.size()+"】consume wait!!!");
                    wait();
                    flag = true;
                }
                if (flag) {
                    System.out.println(Thread.currentThread().getName() + "（Consume被notify了）...");
                }
                System.out.println("---------->"+queue.take());
                notify();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    class Producer implements Runnable {
        Factory factory;

        Producer(Factory factory) {
            this.factory = factory;
        }

        @Override
        public void run() {
            while (true)
                factory.produce("" + System.currentTimeMillis());
        }
    }

    class Consumer implements Runnable {
        Factory factory;

        Consumer(Factory factory) {
            this.factory = factory;
        }

        @Override
        public void run() {
            while (true)
                factory.consume();
        }
    }

    @Test
    public void test(){
        Factory factory = new Factory();
        pool.execute(new Producer(factory));
        pool.execute(new Consumer(factory));
        while (true) {

        }
    }
}
